package com.aube.interact.controller;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;

/**
 * Created by huyaonan on 16/4/19.
 */
public class BezierAnimHelper {

    public BezierAnimHelper() {

    }

    public void startBezierAnim(final IAnimFeedBack iAnim, Point... points) {
        BezierEvaluator evaluator = new BezierEvaluator(points);
        final ValueAnimator anim = ValueAnimator.ofObject(evaluator, points[0], points[points.length-1]);
        anim.setDuration(500);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Point point = (Point) animation.getAnimatedValue();
                float fraction = animation.getAnimatedFraction();
                if (iAnim != null)
                    iAnim.executeAnim(point, fraction);
            }
        });
        anim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                if(iAnim != null)
                    iAnim.animEnd();
            }

        });
        anim.start();
    }

    public interface IAnimFeedBack {
        public void executeAnim(Point point, float fraction);
        public void animEnd();
    }

    public static class Point {
        public int x, y, width, height;
        public Point(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        public Point(float x, float y, float width, float height) {
            this.x = (int) x;
            this.y = (int) y;
            this.width = (int) width;
            this.height = (int) height;
        }
    }

    private class BezierEvaluator implements TypeEvaluator<Point> {

        /**
         * 二次贝赛尔曲线的轨迹公式
         * B(t) = (1 - t)^2 * P0 + 2t * (1 - t) * P1 + t^2 * P2, t ∈ [0,1]
         */

        private Point[] points;

        public BezierEvaluator(Point... points) {
            if(points == null || points.length != 3)
                throw new IllegalArgumentException("must has 3 point at start");
            this.points = points;
        }

        @Override
        public Point evaluate(float fraction, Point startValue, Point endValue) {
            Point p1 = points[0];
            Point p2 = points[1];
            Point p3 = points[2];

            int x = (int) (Math.pow((1f-fraction), 2)*p1.x + 2*fraction*(1f-fraction)*p2.x + Math.pow(fraction, 2)*p3.x);
            int y = (int) (Math.pow((1f-fraction), 2)*p1.y + 2*fraction*(1f-fraction)*p2.y + Math.pow(fraction, 2)*p3.y);
//            int w = (int) (Math.pow((1f-fraction), 2)*p1.width + 2*fraction*(1f-fraction)*p2.width + Math.pow(fraction, 2)*p3.width);
//            int h = (int) (Math.pow((1f-fraction), 2)*p1.height + 2*fraction*(1f-fraction)*p2.height + Math.pow(fraction, 2)*p3.height);
            int w=0;
            int h=0;

            Point target = new Point(x, y, w, h);
            return target;
        }
    }


}
